package com.jvtd.zego;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class JvtdZegoUtils {
    /**
     * 单例.
     */
    public static JvtdZegoUtils sInstance;


    public static final String SHARE_PREFERENCE_NAME = "ZEGO_LIVE";

    public static final String PREFERENCE_KEY_USER_ID = "PREFERENCE_KEY_USER_ID";

    public static final String PREFERENCE_KEY_USER_NAME = "PREFERENCE_KEY_USER_NAME";

    private static final String ZEGO_APP_WEBRTC = "zego_app_webrtc";

    private static final String ZEGO_LIVE_LIVE_QUALITY = "ZEGO_LIVE_LIVE_QUALITY";
    private static final String VIDEO_RESOLUTIONS = "VIDEO_RESOLUTIONS";
    private static final String VIDEO_FPS = "VIDEO_FPS";
    private static final String VIDEO_BITRATE = "VIDEO_BITRATE";
    private static final String VIDEO_FILTER = "VIDEO_FILTER";
    private static final String VIDEO_CAPTURE = "VIDEO_CAPTURE";
    private static final String EXTERNAL_RENDER = "EXTERNAL_RENDER";
    private static final String PREVIEW_MIRROR = "PREVIEW_MIRROR";
    private static final String CAPTURE_MIRROR = "CAPTURE_MIRROR";
    private static final String ENABLE_RATE_CONTROL = "ENABLE_RATE_CONTROL";
    private static final String REQUIRE_HARDWARE_ENCODER = "REQUIRE_HARDWARE_ENCODER";
    private static final String REQUIRE_HARDWARE_DECODER = "REQUIRE_HARDWARE_DECODER";


    private SharedPreferences mSharedPreferences;

    private JvtdZegoUtils(Context context) {
        mSharedPreferences = context.getApplicationContext().getSharedPreferences(SHARE_PREFERENCE_NAME, AppCompatActivity.MODE_PRIVATE);
    }

    public static JvtdZegoUtils getInstance(Context context) {
        if (sInstance == null) {
            synchronized (JvtdZegoUtils.class) {
                if (sInstance == null) {
                    sInstance = new JvtdZegoUtils(context);
                }
            }
        }
        return sInstance;
    }

    @SuppressLint("ApplySharedPref")
    public void setStringValue(String key, String value) {
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putString(key, value);
        editor.commit();
    }

    public String getStringValue(String key, String defaultValue) {
        return mSharedPreferences.getString(key, defaultValue);
    }

    @SuppressLint("ApplySharedPref")
    public void setBooleanValue(String key, boolean value) {
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putBoolean(key, value);
        editor.commit();
    }

    public boolean getBooleanValue(String key, boolean defaultValue) {
        return mSharedPreferences.getBoolean(key, defaultValue);
    }

    @SuppressLint("ApplySharedPref")
    public void setIntValue(String key, int value) {
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putInt(key, value);
        editor.commit();
    }

    public int getIntValue(String key, int defaultValue) {
        return mSharedPreferences.getInt(key, defaultValue);
    }

    @SuppressLint("ApplySharedPref")
    public void setLongValue(String key, long value) {
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putLong(key, value);
        editor.commit();
    }

    public long getLongValue(String key, long defaultValue) {
        return mSharedPreferences.getLong(key, defaultValue);
    }

    public boolean getAPPWebRtc() {
        return getBooleanValue(ZEGO_APP_WEBRTC, false);
    }

    public void setAppWebRtc(boolean v){
        setBooleanValue(ZEGO_APP_WEBRTC, v);
    }

    public Object getObjectFromString(String key) {
        Object value = null;
        try {
            byte[] bytes = Base64.decode(getStringValue(key, ""), Base64.DEFAULT);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            ObjectInputStream oisArray = new ObjectInputStream(bais);
            value = oisArray.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    public void setObjectToString(String key, Object value) {

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos;
            oos = new ObjectOutputStream(baos);
            oos.writeObject(value);
            String data = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
            setStringValue(key, data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void registerOnChangeListener(OnChangeListener listener) {
        mSharedPreferences.registerOnSharedPreferenceChangeListener(listener);
    }

    public void unregisterOnChangeListener(OnChangeListener listener) {
        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(listener);
    }


    public void setLiveQuality(int liveQuality) {
        setIntValue(ZEGO_LIVE_LIVE_QUALITY, liveQuality);
    }

    public void setVideoResolutions(int videoResolutions) {
        setIntValue(VIDEO_RESOLUTIONS, videoResolutions);
    }

    public void setVideoFps(int videoFps) {
        setIntValue(VIDEO_FPS, videoFps);
    }

    public void setVideoBitrate(int videoBitrate) {
        setIntValue(VIDEO_BITRATE, videoBitrate);
    }

    public void setVideoFilter(boolean videoFilter) {
        setBooleanValue(VIDEO_FILTER, videoFilter);
    }

    public void setVideoCapture(boolean videoCapture) {
        setBooleanValue(VIDEO_CAPTURE, videoCapture);
    }

    public void setExternalRender(boolean externalRender) {
        setBooleanValue(EXTERNAL_RENDER, externalRender);
    }

    public void setPreviewMirror(boolean previewMirror) {
        setBooleanValue(PREVIEW_MIRROR, previewMirror);
    }

    public void setCaptureMirror(boolean captureMirror) {
        setBooleanValue(CAPTURE_MIRROR, captureMirror);
    }

    public void setEnableRateControl(boolean enableRateControl) {
        Log.e("zego", "REQUIRE_HARDWARE_ENCODER" + "=" + enableRateControl);
        setBooleanValue(ENABLE_RATE_CONTROL, enableRateControl);
    }

    public void setRequireHardwareEncoder(boolean requireHardwareEncoder) {
        setBooleanValue(REQUIRE_HARDWARE_ENCODER, requireHardwareEncoder);

    }

    public void setRequireHardwareDecoder(boolean requireHardwareDecoder) {
        setBooleanValue(REQUIRE_HARDWARE_DECODER, requireHardwareDecoder);
    }

    public boolean getVideoCapture(boolean defaultValue) {
        return getBooleanValue(VIDEO_CAPTURE, defaultValue);
    }

    public boolean getUseExternalRender(boolean defaultValue) {
        return getBooleanValue(EXTERNAL_RENDER, defaultValue);
    }

    public boolean getVideoFilter(boolean defaultValue) {

        return getBooleanValue(VIDEO_FILTER, defaultValue);
    }

    public boolean getHardwareEncode(boolean defaultValue) {

        return getBooleanValue(REQUIRE_HARDWARE_ENCODER, defaultValue);
    }

    public boolean getHardwareDecode(boolean defaultValue) {
        return getBooleanValue(REQUIRE_HARDWARE_DECODER, defaultValue);
    }

    public boolean getEnableRateControl(boolean defaultValue) {
        return getBooleanValue(ENABLE_RATE_CONTROL, defaultValue);
    }

    public boolean getPreviewMirror(boolean defaultValue) {
        return getBooleanValue(PREVIEW_MIRROR, defaultValue);
    }

    public boolean getCaptureMirror(boolean defaultValue) {
        return getBooleanValue(CAPTURE_MIRROR, defaultValue);
    }

    public int getLiveQuality(int defaultValue) {
        return getIntValue(ZEGO_LIVE_LIVE_QUALITY, defaultValue);
    }

    public int getVideoResolutions(int defaultValue) {

        return getIntValue(VIDEO_RESOLUTIONS, defaultValue);
    }

    public int getVideoFps(int defaultValue) {

        return getIntValue(VIDEO_FPS, defaultValue);
    }

    public int getVideoBitrate(int defaultValue) {
        return getIntValue(VIDEO_BITRATE, defaultValue);
    }

    public static String convertSignKey2String(byte[] signKey) {
        StringBuilder buffer = new StringBuilder();
        for (int b : signKey) {
            buffer.append("0x").append(Integer.toHexString((b & 0x000000FF) | 0xFFFFFF00).substring(6)).append(",");
        }
        buffer.setLength(buffer.length() - 1);
        return buffer.toString();
    }

    public static byte[] parseSignKeyFromString(String strSignKey) throws NumberFormatException {
        String[] keys = strSignKey.split(",");
        if (keys.length != 32) {
            throw new NumberFormatException("App Sign Key Illegal");
        }
        byte[] byteSignKey = new byte[32];
        for (int i = 0; i < 32; i++) {
            int data = Integer.valueOf(keys[i].trim().replace("0x", ""), 16);
            byteSignKey[i] = (byte) data;
        }
        return byteSignKey;
    }


    public interface OnChangeListener extends SharedPreferences.OnSharedPreferenceChangeListener {

    }
}
